/*
@file: variableTable.h
@author: ZZH
@time: 2021-12-29 16:23:25
@info: 基于符号表的变量表
*/
#pragma once
#include "ast.h"
#include "symTable.h"
#include <list>
#include <string>
#include <iostream>
using namespace std;

//多级变量表
class VariableTable_t
{
private:
    using VarSymTable_t = ASTFunctionDef_t::vArgSymTable_t;
    list<VarSymTable_t*> stack;//使用链表堆栈实现变量作用域的管理
    VarSymTable_t glbVariableTable;//全局变量表
    VarSymTable_t* curVariableTable;//当前作用域变量表
protected:

public:
    VariableTable_t() :curVariableTable(&this->glbVariableTable) {}
    ~VariableTable_t()
    {
        cout << "clear glbVariableTable" << endl;
        for (auto pTable : this->stack)//删除符号表即可,符号表析构时会释放它管理的对象
            delete pTable;
    }

    void push(VarSymTable_t* pVarTable)
    {
        this->stack.push_back(this->curVariableTable);
        this->curVariableTable = pVarTable;
    }

    VarSymTable_t* pop()
    {
        if (this->stack.empty())//堆栈内没有压入局部作用域,那么就不可能弹栈
            return nullptr;

        auto cur = this->curVariableTable;
        this->curVariableTable = *this->stack.rbegin();
        this->stack.pop_back();
        return cur;
    }

    inline VarSymTable_t* current() const { return this->curVariableTable; }
    inline VarSymTable_t* global() { return &this->glbVariableTable; }

    inline bool insert(const string& str, ASTVariableDef_t* pVarDef) { return this->curVariableTable->insert(str, pVarDef); }
    inline bool remove(const string& str) { return this->curVariableTable->remove(str); }

    bool search(const string& str, ASTVariableDef_t*& pVarDef) const;
};
extern VariableTable_t VariableTable;
